<?php
/**
 * Created by PhpStorm.
 * User: lee
 * Date: 2018/4/23
 * Time: 上午11:43
 */

namespace Biz\module\Classes\mgt;

use Biz\model\trade\Order as mOrder;
use Biz\model\trade\OrderGoods as mOrderGoods;
use Biz\model\trade\OrderPackage as mOrderPackage;
use Biz\model\trade\OrderRefund as mOrderRefund;
use Biz\model\trade\ShopCourier as mShopCourier;
use Biz\module\Classes\OrderRefund as clsOrderRefund;
use Biz\service\Event;
use Biz\service\Group;
use Biz\service\trade\Logistics as sLogistics;
use Biz\service\trade\ShopAddress as sShopAddress;
use Biz\service\trade\ShopCourier as sShopCourier;
use Doraemon\tools\Log as tLog;


class Order
{
    public static function shipOrder($orderNo, $expressData, $shopId, $courierId, $isMulti = false, $skuIds = '')
    {
        $data = [];
        $nowTime = time();
        $whereSkuIds = [];

        //如果是分单发货，则设置数据格式
        $checkSendAll = false;
        $isPackageDelivery = false;

        $skuIds = trim($skuIds, ',');

        $courierInfo = sShopCourier::getCourierFileInfo($courierId);

        if (!empty($courierInfo)) {
            $expressData['express_company'] = $courierInfo['courier_name'];
        }


        $shopAddress = sShopAddress::getDefaultAddressByShopId($shopId);

        if (empty($shopAddress)) {
            throw new \Exception('发货前请先设置默认退货地址');
        }


        //根据此次发货的商品，判断是否部分发货，以及是否最后一个包裹
        self::beforeShipOrderCheck($orderNo, $skuIds, $whereSkuIds, $isPackageDelivery, $checkSendAll);

        if (empty($skuIds)) {
            throw new \Exception('请选择商品的SKU_ID');
        }


        $result = mOrder::action(function () use ($orderNo, $courierId, &$packageId, $shopId, &$data, $expressData, &$orderInfo, &$logistics, $courierInfo, &$refundingStatus, $isMulti, &$refundSkuInfo, &$skuIds, $whereSkuIds, &$checkSendAll, $isPackageDelivery, $nowTime) {

            //获取订单信息
            $orderInfo = mOrder::getOrderInfoFromMaster($orderNo);

            if (!$isMulti) {//批量发货不用验证  前面已验证
                if ($orderInfo['shop_id'] != $shopId) {
                    throw new \Exception('该商家没有此订单号');
                }

                if (!mOrder::checkStatusCanShip($orderInfo['status'])) {
                    throw new \Exception('请核实订单的状态');
                }

                //拼团中的订单不允许发货
                $groupOrder = Group::getShopJoinOrder($shopId, '', '', $orderNo);
                if (!empty($groupOrder)) {
                    throw new \Exception('拼团商品请在拼团成功后发货');
                }
            }

            if (!preg_match('/^[a-zA-Z0-9]+$/', $expressData['express_no'])) {
                throw new \Exception('快递单号不是正确格式');
            }


            //判断是否有处理中的退款申请
            $clsOrderRefund = new clsOrderRefund();
            $refundingStatus = $clsOrderRefund->checkOrderHasRefunding([$orderNo => mOrder::STATUS_WAIT_SEND], 'mgtShip', false, $whereSkuIds);

            if ($refundingStatus == clsOrderRefund::REFUND_WAIT_APPLY) {
                throw new \Exception('买家申请了退款，请处理后再发货');
            }

            //如果有维权中的则不允许发货
            if ($refundingStatus == clsOrderRefund::REFUNDING_RIGHTS_IN) {
                throw new \Exception('商品退款正在维权中，请等待维权判定完毕后再发货');
            }


            //判断是否订单全额退款
            $checkFullRefund = mOrderRefund::checkIsFullRefund($orderNo, $orderInfo['pay_amount']);
            if ($checkFullRefund) {
                throw new \Exception('订单已全额退款，不能发货');
            }


            //如果是有处理中的退款申请，则将退款申请的状态设置为退款取消
            if ($refundingStatus == clsOrderRefund::REFUNDING_YES) {

                $refundSkuInfo = mOrderRefund::getFirstRefundingSkuInfo($orderNo, $whereSkuIds);

                $clsOrderRefund->cancelOrderRefundList($orderNo, ['cancel_refund'], $whereSkuIds);
            }


            //部分发货是否已全部发出
            if ($checkSendAll) {//最后一次部分发货
                $data['status'] = mOrder::STATUS_SEND_OUT;
                $data['delivery_time'] = date('Y-m-d H:i:s', $nowTime);
                $data['autoconfirm_time'] = date('Y-m-d H:i:s', $nowTime + mOrder::MAX_WAIT_AUTO_CONFIRM_TIME);

            } else {
                $data['status'] = mOrder::STATUS_SEND_PART_OUT;
            }


            $data['is_package_delivery'] = mOrder::IS_PACKAGE_DELIVERY_YES;


            if ($courierId != mShopCourier::SELF_LIFTING_ID) {
                //分单发货，创建包裹
                $packageId = mOrderPackage::createPackage($orderInfo['uid'], $orderNo, implode(',', $skuIds), $expressData['express_company'], $expressData['express_no']);
            } else {
                $packageInfo = mOrderPackage::getFirstPackageInfo($orderNo);
                if ($packageInfo) {
                    $packageId = $packageInfo['id'];
                } else {
                    throw new \Exception('非门店自提订单不能选择门店自提发货');
                    // $packageId = mOrderPackage::createPackage($orderInfo['uid'], $orderNo, implode(',', $skuIds), '门店自提', $expressData['express_no']);
                }
            }


            $ret = mOrder::updateData($data, ['order_no' => $orderNo,]);

            //如果不是门店自提则需要进行物流订阅

            $logistics = [];
            $logistics['order_no'] = $orderNo;
            $logistics['express_no'] = $expressData['express_no'];
            $logistics['package_id'] = $packageId;
            $logistics['uid'] = (int)$orderInfo['uid'];
            $logistics['shop_id'] = (int)$shopId;
            $logistics['addtime'] = date('Y-m-d H:i:s', $nowTime);
            $logistics['edittime'] = date('Y-m-d H:i:s');
            $logistics['courierbird_code'] = $courierInfo['courierbird_code'] ?: 0;
            $logistics['trackingmore_code'] = $courierInfo['trackingmore_code'] ?: 0;
            tLog::debug('test', $logistics);
            //订阅
            sLogistics::subscribe($logistics);

            return true;
        });


        if ($result !== false) {

            if (isset($orderInfo) && !empty($orderInfo)) {

                $eventId = Event::genUniqId();

                $eventData = [
                    'shop_id' => $shopId,
                    'order_no' => $orderNo,
                    'sku_ids' => array_values($skuIds),
                    'refunding_status' => $refundingStatus,
                    'courier_id' => $courierId,
                    'express_company' => $expressData['express_company'],
                    'express_no' => $expressData['express_no'],
                    'is_multi' => (int)$isMulti
                ];

                if ($data['is_package_delivery'] == mOrder::IS_PACKAGE_DELIVERY_YES) {
                    if ($checkSendAll) {
                        Event::push(Event::ORDER_SHIP_ALL_DELIVERY_SUCCESS, array_merge($eventData, [
                            'package_id' => $packageId,
                            'is_package_delivery' => 1,
                            'is_delivery_all' => 1,
                            'uniq_idx' => ['order_no', 'event_tag']
                        ]), $eventId);
                    } else {
                        //订单分单发货成功的事件
                        Event::push(Event::ORDER_SHIP_PART_DELIVERY_SUCCESS, array_merge($eventData, [
                            'package_id' => $packageId,
                            'is_package_delivery' => 1,
                            'is_delivery_all' => 0,
                            'uniq_idx' => ['order_no', 'event_tag', 'package_id']
                        ]), $eventId);
                    }
                } else {
                    Event::push(Event::ORDER_SHIP_ALL_DELIVERY_SUCCESS, array_merge($eventData, [
                        'package_id' => $packageId,
                        'is_package_delivery' => 0,
                        'is_delivery_all' => 1,
                        'uniq_idx' => ['order_no', 'event_tag']
                    ]), $eventId);
                }


            }
        }
        return $result;
    }

    protected static function beforeShipOrderCheck($orderNo, &$skuIds, &$whereSkuIds, &$isPackageDelivery, &$checkSendAll)
    {
        if (!empty($skuIds)) {
            $skuIds = array_filter(explode(',', $skuIds));

            $skuIdList = mOrderGoods::getSkuIds($orderNo);

            array_map(function ($v) use ($skuIdList) {
                if (!in_array($v, $skuIdList)) {
                    throw new \Exception('上传的发货SKU_ID，有错，请重新上传');
                }
            }, $skuIds);

            //无论外界传什么列表，都必须与数据库中的skuids进行交集比较
            $skuIds = array_intersect($skuIdList, $skuIds);

            if (count($skuIdList) != count($skuIds)) {

                $skuIsDelivery = mOrderPackage::checkSkuIdsDelivery($orderNo, $skuIds);

                if ($skuIsDelivery) {
                    throw new \Exception('提交的SKUID已发货，不可再次发货', 7777);
                }

                $isPackageDelivery = true;
            }

            if (!empty($skuIds)) {
                //分单发货，则判断此次发货是否是最后一次
                $checkSendAll = mOrderPackage::checkSendAll($orderNo, $skuIds, $skuIdList);


                $whereSkuIds = ['sku_id' => $skuIds];
            }


        }
    }
}